package com.jml.aop.demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *jdk代理：代理接口所有的实现方法
 * 		JDK动态代理：其代理对象必须是某个接口的实现，它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理
 *
 *CGLIB代理：代理对象的所有方法
 * 		CGLIB代理：实现原理类似于JDK动态代理，只是它在运行期间生成的代理对象是针对目标类扩展的子类。
 * 		CGLIB是高效的代码生成包，底层是依靠 ASM（开源的Java字节码编辑类库）操作字节码实现的，性能比JDK强
 *
 *expose-proxy ：有时候目标对 内部的自我调用将无法实施切面中的增强,需要加入这个就可以实现
 *
 *proxy-target-class:SpringAOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理(建议尽量使用JDK的动态代理)。
 *	如果被代理的目标对象实现了至少一个接口，则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。
 *	若该目标对象没有实现任何接口，则创建一个 CGLIB代理。
 *	如果你希望强制使用CGLIB代理（例如希望代理目标对象的所有方法，而不只是实现自接口的方法），那也可以。
 *使用CGHLIB代理存在两个问题：
 *	1.无法通知（ advise） Final方法，因为它们不能被覆写。
 *	2.你需要将CGLIB二进制发行包放在classpath下面。
 *
 * 强制使用CGLIB代理需要将<aop:config>的proxy-target-class属性设置为true
 * 		<aop:config proxy-target-class=true>...</aop:config>
 *
 * 当需要使用CGLIB代理和@AspectJ自动代理支持，可以按照以下方式设置<aop:aspectj-autoproxy>的 proxy-target-class属性
 * 		<aop:aspectj-autoproxy proxy-target-class=true>...</aop:aspectj-autoproxy>
 *
 * 	1.hadler配置文件和先通过命名空间初始化AopNamespaceHandler,把AspectJAutoProxyBeanDefinitionParser放入容器，
 * 	然后执行他的parse方法生成一个BeanDefinition放入BeanFactory
 * 	的map中，就是AnnotationAwareAspectJAutoProxyCreator，
 * 	他的子类继承了后置处理器接口，先会初始化这个类然后把这个类放入beanFactory的后置处理器的集合，
 * 	在初始化所有懒加载的类的时候，所有的类都会走他的后置处理器
 *
 *
 * 	<aop:aspectj-autoproxy/>
 */
public class MainTest {

	/**
	 *
	 * @param args
	 */
	public static void main(String[] args) {

		ApplicationContext bf = new ClassPathXmlApplicationContext("/aop/DemoTest.xml");
		TestBean bean = (TestBean)bf.getBean("test1");
		bean.test();
	}
}
